_TITLE "BAM Draw"
' Program by Charlie Veniot
' This program exported from BASIC Anywhere Machine (Version [5.2.3].[2023.10.26.02.14]) on 2023.11.13 at 01:26 (Coordinated Universal Time)
OPTION EXPLICIT

' 🟠🟠🟠 DECLARATIONS

'πŸ—’ multi-use general-purpose variables
    VAR t$, this_mark$, this_marker$, this_f_color%, this_b_color%
    VAR i%, iy%, ix%

'πŸ—’ screen variables
    CONST minw% = 33, maxw% = 260, minh% = 1, maxh% = 60
    VAR w% = 0, h% = 0
    VAR grid% = TRUE
  
'πŸ—’ menu constants / variables
    CONST menuh% = 3 ' number of rows in footer menu
    CONST fc4bc%(0 to 15) = {15,15,15,15,15,15,15,0,15,15,0,0,0,0,0,0}
    VAR color_menu_mode$ = "Foreground"
    
    'πŸͺ§ mi = menu item, mic = menu item count
    CONST mic% = 8 ' vmic = variable menu items count
    CONST mi$(1 TO mic%) = { "Grid","Wdth","Hght","MovL","MovR","MovU","MovD","Xprt" }
    FOR i% = 1 TO mic% : _MAPSET(mi$(i%), i%) : NEXT i%
    
    VAR menu_pick$ = "Grid"
  
'πŸ—’ marker variables
    VAR marker$ = " "
    VAR f_color% = 15, b_color% = 0
  
'πŸ—’ mouse/touch variables  
    VAR x%, y%
  
' 🟠🟠🟠 MAIN PROGRAM

GOSUB βš™130_init_program

πŸ”ƒdrawing_cycle:
  _DISPLAY
  LET t$ = INKEY$
  IF t$ > "" THEN marker$ = t$ : GOSUB βœ’530_set_marker
  IF _MOUSEBUTTON THEN
     IF _MOUSEZONE (0, 0, _WIDTH, [_HEIGHT-(menuh%*8)] ) _
        THEN GOSUB βœ’520_do_marking : GOTO ⏩done
     WHILE _MOUSEBUTTON : WEND
     IF _MOUSEZONE(40, yMAX - 7, 64, 8 ) _
        THEN GOSUB βœ’510_change_marker : GOTO ⏩done
     IF _MOUSEZONE(0, yMAX - 15, 32, 8 ) _
        THEN GOSUB πŸ”320_show_next_menu_item : GOTO ⏩done
     IF _MOUSEZONE(0, yMAX - 7, 32, 8 ) _
        THEN GOSUB πŸ”330_toggle_menu_pick : GOTO ⏩done
     IF _MOUSEZONE(8*5, yMAX - 15, 88, 8 ) _
        THEN GOSUB 🎨640_toggle_color_menu_mode : GOTO ⏩done
     IF _MOUSEZONE(8*6+80, yMAX - 15, 128, 16 ) _
        THEN GOSUB 🎨610_change_color : GOTO ⏩done
     ⏩done:
  END IF
  
GOTO πŸ”ƒdrawing_cycle

END

' 🟠🟠🟠 SUBROUTINES
  ' Groupings:
    ' βš™100 Settings
    ' πŸ–₯200 Screen
    ' πŸ”300 Menu
    ' πŸ–Ό400 Grid
    ' βœ’500 Marker
    ' 🎨600 Color
    ' πŸ”§700 Tools
    ' 🧭800 Move Drawing 

βš™110_continue_drawing:
  LET marker$ = NVL$( GetLocalStorageItem( "draw:marker" ), " " )
	LET f_color% = GetLocalStorageItem( "draw:f_color" )
	LET b_color% = GetLocalStorageItem( "draw:b_color" )
  GOSUB πŸ–₯220_setup_screen
  GOSUB πŸ–₯210_refresh_canvas
  GOSUB πŸ–Ό410_do_grid
  RETURN
  
βš™120_do_new_drawing:
     FOR iy% = 1 TO MAX(GetLocalStorageItem( "draw:height" ), maxh%)
         FOR ix% = 1 TO MAX(GetLocalStorageItem( "draw:height" ), maxw% )
             RemoveLocalStorageItem("draw:mark:" + iy% +"," + ix%)
         NEXT ix%
     NEXT iy%
     GOSUB βš™150_prompt_width
     GOSUB βš™140_prompt_height
     SetLocalStorageItem( "draw:f_color", 15 )
     SetLocalStorageItem( "draw:b_color", 0 )
     GOSUB βœ’530_set_marker
     GOSUB πŸ–₯220_setup_screen
  RETURN
  
βš™130_init_program:
  IF GetLocalStorageItem( "draw:height" ) > "" _
     THEN LET t$ = NVL$(_PROMPT("Continue previous drawing or start a new drawing?\n\n  'C' to continue previous drawing, 'N' for new drawing", "C"), "C")
  IF UCASE$( t$ ) = "C" _
     THEN GOSUB βš™110_continue_drawing _
     ELSE GOSUB βš™120_do_new_drawing
  RETURN

βš™140_prompt_height:
  LET i% = _PROMPT( "Canvas Width (i.e. how many characters wide, minimum = " + minh% + ", maximum = " + maxh% + ")", MAX(h%/8-3, 20) )
  LET i% = MIN( IFF( i% < minh%, MAX(h%/8-3, 20), i% ), maxh%)
  SetLocalStorageItem( "draw:height", i% )
  RETURN

βš™150_prompt_width:
  LET i% = _PROMPT( "Canvas Width (i.e. how many characters wide, minimum = " + minw% + ", maximum = " + maxw% + ")", MAX(w%/8,minw%) )
  LET i% = MIN( IFF(i% < minw%,MAX(w%/8,minw%), i%), maxw%)
  SetLocalStorageItem( "draw:width", i% )
  RETURN
  
πŸ–₯210_refresh_canvas:
  FOR iy% = 1 TO MAX( minh% , GetLocalStorageItem( "draw:height" ) )
      FOR ix% = 1 TO MAX( minw%, GetLocalStorageItem( "draw:width" ) )
          LET this_mark$ = GetLocalStorageItem( "draw:mark:" + iy% + "," + ix%)
          IF this_mark$ <> "" THEN
             LET this_marker$ = LEFT$(this_mark$, 1) : LET this_mark$ = RIGHT$(this_mark$, LEN(this_mark$) - 2)
				     LET this_f_color% = VAL(LEFT$(this_mark$, INSTR(this_mark$, ",") - 1))
				     LET this_b_color% = VAL(RIGHT$(this_mark$, LEN(this_mark$) - INSTR(this_mark$, ",")))
				     COLOR this_f_color%, this_b_color%
             LOCATE iy%, ix% : PRINT this_marker$;
          ELSE
				     COLOR 15, 0 : LOCATE iy%, ix% : PRINT " ";
          END IF
      NEXT ix%
  NEXT iy%
  IF grid% THEN GOSUB πŸ–Ό410_do_grid
  RETURN

πŸ–₯220_setup_screen:
  LET w% = [ MAX(minw%, GetLocalStorageItem( "draw:width" ) ) ] * 8
  LET h% = [ MAX(minh%, GetLocalStorageItem( "draw:height" ) ) + menuh% ] * 8 
  SCREEN _NEWIMAGE( w%, h%, 7 )
  GOSUB πŸ–Ό410_do_grid
  COLOR 15, 0
  LINE (0,_HEIGHT-20) TO (xMAX,_HEIGHT-20) : LINE (35,_HEIGHT-20) TO (36, yMAX), ,B
  LOCATE (_HEIGHT/8), 1 : PRINT STRING$(4,CHR$(240));
  LOCATE (_HEIGHT/8), 6 : PRINT "Marker:"; : GOSUB βœ’530_set_marker
  GOSUB πŸ”310_show_menu_pick
  GOSUB 🎨620_show_color_menu
  GOSUB 🎨630_show_color_picks
  RETURN

πŸ”310_show_menu_pick: 
  COLOR 15, 0
  LOCATE (_HEIGHT/8)-1, 1 : PRINT menu_pick$;
  RETURN
  
πŸ”320_show_next_menu_item:
  ON _MAPGET(menu_pick$)        _
     GOSUB πŸ–Ό420_toggle_grid,   _
           βš™150_prompt_width,  _
           βš™140_prompt_height, _
           🧭810_MovL,          _
           🧭820_MovR,          _
           🧭830_MovU,          _
           🧭840_MovD, _
           πŸ”§710_do_export
  IF BETWEEN(_MAPGET(menu_pick$),2,7) THEN GOSUB πŸ–₯220_setup_screen : GOSUB πŸ–₯210_refresh_canvas
  RETURN
  
πŸ”330_toggle_menu_pick:
  i% = _MAPGET(menu_pick$) + 1 : IF i% > mic% THEN i% = 1
  menu_pick$ = mi$(i%)
  GOSUB πŸ”310_show_menu_pick
  RETURN
  
πŸ–Ό410_do_grid:
     FOR i% = 0 TO xMAX STEP 8
  	     LINE (i%,0) TO (i%,(yMAX-menuh%*8)), 7
     NEXT i%
     FOR i% = 7 TO (yMAX-menuh%*8) STEP 8
         LINE (0,i%) TO (xMAX,i%), 7
     NEXT i%
  RETURN
  
πŸ–Ό420_toggle_grid:
  grid% = NOT grid%
  IF grid% THEN GOSUB πŸ–Ό410_do_grid ELSE GOSUB πŸ–Ό430_undo_grid
  RETURN
  
πŸ–Ό430_undo_grid:
     FOR i% = 0 TO xMAX STEP 8
  	     LINE (i%,0) TO (i%,(yMAX-menuh%*8)), 0
     NEXT i%
     FOR i% = 7 TO (yMAX-menuh%*8) STEP 8
         LINE (0,i%) TO (xMAX,i%), 0
     NEXT i%
     GOSUB πŸ–₯210_refresh_canvas
  RETURN

βœ’510_change_marker:
  LET marker$ = LEFT$(_PROMPT("Enter one simple keyboard character as a new marker shape.", marker$)+marker$, 1)
  GOSUB βœ’530_set_marker
  RETURN
  
βœ’520_do_marking:
  LET x% = _MOUSEX : LET y% = _MOUSEY
  LET iy% = FIX(y%/8)+1 : LET ix% = FIX(x%/8)+1
  COLOR f_color%, b_color%
  LOCATE iy%, ix% : PRINT marker$;
  IF grid% THEN GOSUB πŸ–Ό410_do_grid 
  SetLocalStorageItem( "draw:mark:" + iy% + "," + ix%, marker$ + " " + f_color% + "," + b_color%)
  RETURN

βœ’530_set_marker:
	LOCATE (_HEIGHT/8), 13 : COLOR f_color%, b_color% : PRINT marker$;
	SetLocalStorageItem( "draw:marker", marker$ )
	RETURN
  
🎨610_change_color:
  LET f_color% = IFF(color_menu_mode$="Foreground", POINT(_MOUSEX,_MOUSEY), f_color%)
  LET b_color% = IFF(color_menu_mode$="Background", POINT(_MOUSEX,_MOUSEY), b_color%)
	SetLocalStorageItem( "draw:f_color", f_color% )
	SetLocalStorageItem( "draw:b_color", b_color% )
  GOSUB 🎨630_show_color_picks
  GOSUB βœ’530_set_marker
  RETURN

🎨620_show_color_menu:
  COLOR 15,0
  LOCATE (_HEIGHT/8)-1, 6 : PRINT color_menu_mode$ + ":";
  RETURN
  
🎨630_show_color_picks:
  FOR i% = 0 TO 15
	   LOCATE (_HEIGHT/8)-IFF(i% < 8, 1, 0),17+([i%-IFF(i% < 8, 0, 8)]*2) : COLOR i%, 0 : PRINT CHR$(219) + CHR$(219);
     IF i% = f_color% THEN LOCATE (_HEIGHT/8)-IFF(i% < 8, 1, 0),17+([i% - IFF(i% < 8, 0, 8)]*2) : COLOR fc4bc%(i%),i% : PRINT "F";
     IF i% = b_color% THEN LOCATE (_HEIGHT/8)-IFF(i% < 8, 1, 0),17+([i% - IFF(i% < 8, 0, 8)]*2)+1 : COLOR fc4bc%(i%),i% : PRINT "B";
  NEXT i%
  RETURN
  
🎨640_toggle_color_menu_mode:
  LET color_menu_mode$ = IFF(color_menu_mode$="Foreground", "Background", "Foreground")
  GOSUB 🎨620_show_color_menu
  RETURN
  
πŸ”§710_do_export:
  OPEN "YourDrawing.bas" FOR OUTPUT AS #1
  PRINT#1, "SCREEN _NEWIMAGE( " + w% + ", " + (h%-24) + ", 7 )" 
  PRINT#1, ""
  PRINT#1, "DO"
  PRINT#1, SPC(2) + "READ row%, col%, marker$, f_color%, b_color%"
  PRINT#1, SPC(2) + "IF marker$ <> " + CHR$(34) + "END" + CHR$(34) + " THEN _"
  PRINT#1, SPC(4) + "COLOR f_color%, b_color%"
  PRINT#1, SPC(4) + "LOCATE row%, col% : PRINT marker$;"
  PRINT#1, "LOOP UNTIL marker$ = " + CHR$(34) + "END" + CHR$(34)
  PRINT#1, ""
  FOR iy% = 1 TO MAX( minh% , GetLocalStorageItem( "draw:height" ) )
      FOR ix% = 1 TO MAX( minw%, GetLocalStorageItem( "draw:width" ) )
          LET this_mark$ = GetLocalStorageItem( "draw:mark:" + iy% + "," + ix%)
          IF this_mark$ <> "" THEN
             LET this_marker$ = LEFT$(this_mark$, 1) : LET this_mark$ = RIGHT$(this_mark$, LEN(this_mark$) - 2)
				     LET this_f_color% = VAL(LEFT$(this_mark$, INSTR(this_mark$, ",") - 1))
				     LET this_b_color% = VAL(RIGHT$(this_mark$, LEN(this_mark$) - INSTR(this_mark$, ",")))
             PRINT#1, "DATA " + iy% + ", " + ix% + ", " + CHR$(34) + this_marker$ + CHR$(34) + ", " + this_f_color% + ", " + this_b_color%
          END IF
      NEXT ix%
  NEXT iy%
  PRINT#1, "DATA -99, -99, " + CHR$(34) + "END" + CHR$(34) + ", -99, -99"
  CLOSE #1
  RETURN

' 🧭🧭🧭 Move Drawing

  SUB Mov_slsi(y%,x%)
      SetLocalStorageItem( "draw:mark:" + iy% + "," + ix%, GetLocalStorageItem("draw:mark:" + y% + "," + x% ) )
  END SUB
  DEF FN_h = GetLocalStorageItem("draw:height")
  DEF FN_w = GetLocalStorageItem("draw:width")

🧭810_MovL: FOR iy% = 1 TO FN_h : FOR ix% = 1 TO FN_w
            CALL Mov_slsi(iy%,ix%+1) : NEXT ix%, iy%
        RETURN
  
🧭820_MovR: FOR iy% = 1 TO FN_h : FOR ix% = FN_w TO 1 STEP -1
            CALL Mov_slsi(iy%,ix%-1) : NEXT ix%, iy%
        RETURN
  
🧭830_MovU: FOR iy% = 1 TO FN_h : FOR ix% = 1 TO FN_w
            CALL Mov_slsi(iy%+1,ix%) : NEXT ix%, iy%
        RETURN
  
🧭840_MovD: FOR iy% = FN_h TO 1 STEP - 1 : FOR ix% = 1 TO FN_w
            CALL Mov_slsi(iy%-1,ix%) : NEXT ix%, iy%
        RETURN